home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Snippets / NewLace 1.1.1 / NewLace.c < prev    next >
Encoding:
Text File  |  1995-12-15  |  14.0 KB  |  611 lines  |  [TEXT/CWIE]

  1. // NewLace
  2. // version 1.1.1
  3. // by Ken Long <kenlong@netcom.com>
  4. // updated to CW7 and THINK 7 on 951201
  5.  
  6. //• --------------------------------------------------------------- •//
  7. //• An itty bitty bytes™ rewrite of the old MS QuickBasic demo
  8. //• done on 25 September 1995, by Kenneth A. Long.
  9. //• This is a Public Domain source code project for Novice C
  10. //• programmers.
  11. //• --------------------------------------------------------------- •//
  12. //• If you put this on a medium, such as a CD or magnetic disk,
  13. //• which is then sold, you must send me free copy.
  14. //• kenlong@netcom.com
  15. //• --------------------------------------------------------------- •//
  16.  
  17. //• --------------------------------------------------------------- •//
  18. //• NewLace.c
  19. //• --------------------------------------------------------------- •//
  20.  
  21. #include <Picker.h>
  22. #include <GestaltEqu.h>
  23.  
  24. #define over qd.screenBits.bounds.right
  25. #define under qd.screenBits.bounds.bottom
  26. #define yo true        //• Why type 4 leeters when you can type 2?
  27. #define no false
  28.  
  29. //• --------------------------------------------------------------- •//
  30. long ticks;
  31. WindowPtr    laceWind;
  32. Rect    dragRect;
  33. Rect    windRect;
  34. Rect    laceRect = {  0, 0, 27, 27 };
  35.  
  36. Boolean plus, minus, up, down, square, round, quit = false,
  37.         pause, color, toggle, both, bw, degrees_30;
  38.         
  39. short diameter, howWide, howHigh, offset;
  40.  
  41. Str255 title = {
  42.     "\pDiameter: 27, Offset: 2 • 'K' for keys."
  43. }; //• 12345678901234567890123456789012345678
  44. //•              ^11         ^22
  45. //•             ^10       ^20       ^30
  46.  
  47. //• --------------------------------------------------------------- •//
  48. //• Prototypes:
  49.  
  50. Boolean WeGotHues (void);
  51. void Originals (void);
  52. void DisplayData (void);
  53. void DoAbout (void);
  54. void DoKeys (void);
  55. void StartOver (Boolean original);
  56. short SelectColor (RGBColor *colorPtr);
  57. void SetForeColor (short red, short green, short blue);
  58. void SetBackColor (short red, short green, short blue);
  59. void FigureDirection (void);
  60. void DoLines (void);
  61. void Draw (void);
  62. void SetUpWindow (void);
  63. void InitMacintosh (void);
  64. void HandleMouseDown (EventRecord *theEvent);
  65. short HandleEvent (void);
  66. void main (void);
  67. //• 
  68.  
  69. //• --------------------------------------------------------------- •//
  70. //• Routines:
  71. //• --------------------------------------------------------------- •//
  72.  
  73. //• --------------------------------------------------------------- •//
  74. Boolean WeGotHues (void)
  75. {
  76.     unsigned char    version[ 4 ];
  77.     OSErr            err;
  78.     
  79.     err = Gestalt (gestaltQuickdrawVersion, (long *)version);
  80.     
  81.     if (version[ 2 ] > 0)
  82.         return (true);
  83.     else
  84.         return (false);
  85. }
  86.  
  87. //• --------------------------------------------------------------- •//
  88. //• Initial settings.
  89. void Originals ()
  90. {
  91.     plus         = yo, 
  92.     minus         = no, 
  93.     up             = no, 
  94.     down         = yo,
  95.     square         = no, 
  96.     round         = yo, 
  97.     pause         = no, 
  98.     color         = no,
  99.     toggle         = yo, 
  100.     both         = no, 
  101.     bw             = yo, 
  102.     degrees_30     = no;
  103.  
  104.     howWide = 27;
  105.     howHigh = 27;
  106.     offset = 2;
  107. }
  108.  
  109. //• --------------------------------------------------------------- •//
  110. //• Display the diameter and offset, of the sprite,
  111. //• in the title bar of the window.
  112. void DisplayData ()
  113. {    
  114.     diameter = laceRect.right - laceRect.left;
  115.     
  116.     if (diameter > 99)
  117.         diameter = 99;
  118.         
  119.     if (diameter < 5)
  120.         diameter = 5;
  121.  
  122.     if (offset > 9)
  123.         offset = 9;
  124.         
  125.     if (offset < 1)
  126.         offset = 1;
  127.  
  128.     if (diameter < 10)
  129.     {
  130.          NumToString (diameter, (title + 11));
  131.         title[11] = '0';
  132.     }
  133.     else
  134.          NumToString (diameter, (title + 10));
  135.          
  136.     NumToString (offset, (title + 22));
  137.  
  138.     //• NumToString inserts a '\0' we don't need.
  139.     *(title + 10) = ' ';
  140.     *(title + 22) = ' ';
  141.     SetWTitle(laceWind, title);
  142. }
  143.  
  144. //• --------------------------------------------------------------- •//
  145. //• Draw the "About" picture.
  146. void DoAbout ()
  147. {
  148.     PicHandle pict;
  149.     Rect picRect;
  150.     short T, L, B, R;
  151.     
  152.     if (WeGotHues ())
  153.         pict = GetPicture (128);
  154.     else
  155.         pict = GetPicture (130);
  156.     
  157.     T = (under / 2) - ((*pict)->picFrame.bottom / 2) - 10;
  158.     L = (over / 2) - ((*pict)->picFrame.right / 2);
  159.     B = T + (*pict)->picFrame.bottom;
  160.     R = L + (*pict)->picFrame.right;
  161.     
  162.     
  163.     EraseRect (&laceWind->portRect);
  164.     SetRect (&picRect, L, T, R, B);
  165.     DrawPicture (pict, &picRect);
  166.     Delay (240L, &ticks);
  167.     ReleaseResource ((Handle)pict);
  168.     EraseRect (& laceWind->portRect);
  169.     StartOver (no);
  170. }
  171.                        
  172. //• --------------------------------------------------------------- •//
  173. //• Draw the "Keys" picture.
  174. void DoKeys ()
  175. {
  176.     PicHandle pict;
  177.     Rect picRect;
  178.     short T, L, B, R;
  179.     
  180.     if (WeGotHues ())
  181.         pict = GetPicture (129);
  182.     else
  183.         pict = GetPicture (131);
  184.     
  185.     
  186.     T = (under / 2) - ((*pict)->picFrame.bottom / 2) - 10;
  187.     L = (over / 2) - ((*pict)->picFrame.right / 2);
  188.     B = T + (*pict)->picFrame.bottom;
  189.     R = L + (*pict)->picFrame.right;
  190.     
  191.     
  192.     EraseRect (&laceWind->portRect);
  193.     SetRect (&picRect, L, T, R, B);
  194.     DrawPicture (pict, &picRect);
  195.     Delay (300L, &ticks);
  196.     ReleaseResource ((Handle)pict);
  197.     EraseRect (& laceWind->portRect);
  198.     StartOver (no);
  199. }
  200.  
  201. //• --------------------------------------------------------------- •//
  202. //• Starts the sprite on a blank screen in the upper-left corner.
  203. //• Blanks screen with background color - default is white.
  204. void StartOver (Boolean original)
  205. {
  206.     diameter = laceRect.right - laceRect.left;
  207.     
  208.     EraseRect (&laceWind->portRect);
  209.     
  210.     //• If original is passed, set the rect as it was on luanch.
  211.     if (original)
  212.     {
  213.         SetRect (&laceRect, 0, 0, 27, 27);
  214.         offset = 2;
  215.         degrees_30 = no;
  216.         howWide = 27;
  217.         howHigh = 27;
  218.         round = yo;
  219.         
  220.     }
  221.     
  222.     //• Otherwise, use diameter previously set, in upper left corner.
  223.     else
  224.         SetRect (&laceRect, 0, 0, howWide, howHigh);
  225.     
  226.     DisplayData ();
  227.  
  228.     //• Make it go down and to the right.
  229.     down     = yo;
  230.     up         = no;
  231.     plus     = yo;
  232.     minus     = no;
  233. }
  234.  
  235. //• --------------------------------------------------------------- •//
  236. //• Calls the color picker.
  237. short SelectColor (RGBColor *colorPtr)
  238. {
  239.     Point    where;
  240.     
  241.     where.h = -1;
  242.     where.v = -1;
  243.     
  244.     return (GetColor (where, "\pChoose background color", colorPtr,
  245.                 colorPtr));
  246. }
  247.  
  248. //• --------------------------------------------------------------- •//
  249. //• Sets the 3 RGBForeColor struct members to what's passed in.
  250. //• (Not used, this trip.)
  251. void SetForeColor (short red, short green, short blue)
  252. {
  253.     RGBColor crayola;
  254.     
  255.     crayola.red = red;
  256.     crayola.green = green;
  257.     crayola.blue = blue;
  258.  
  259.     RGBForeColor (&crayola);
  260. }
  261.  
  262. //• --------------------------------------------------------------- •//
  263. //• Sets the 3 RGBBackColor struct members to what's passed in.
  264. //• (Not used, this trip.)
  265. void SetBackColor (short red, short green, short blue)
  266. {
  267.     RGBColor crayola;
  268.     
  269.     crayola.red = red;
  270.     crayola.green = green;
  271.     crayola.blue = blue;
  272.  
  273.     RGBBackColor (&crayola);
  274. }
  275.  
  276. //• --------------------------------------------------------------- •//
  277. //• Sets the driection of sprite according to window edge hit.
  278. void FigureDirection ()
  279. {
  280.     Rect winder = laceWind->portRect;
  281.     
  282.     //• Sprite bottom greater than window bottom?
  283.     if (laceRect.bottom > winder.bottom)
  284.     {
  285.         down = no;        //• Change down to up...
  286.         up = yo;
  287.     }
  288.     //• Sprite right greater than window right?
  289.     if (laceRect.right > winder.right)
  290.     {
  291.         plus = no;        //• Change right to left...
  292.         minus = yo;
  293.     }
  294.     //• Sprite top lesser than window top?
  295.     if (laceRect.top < winder.top)
  296.     {
  297.         up = no;        //• Change up to down...
  298.         down = yo;
  299.         
  300.     }
  301.     //• Sprite left lesser than window left?
  302.     if (laceRect.left < winder.left)
  303.     {
  304.         minus = no;        //• Change left to right...
  305.         plus = yo;
  306.     }
  307. }
  308.  
  309. //• --------------------------------------------------------------- •//
  310. //• Draws a grid based on sprite diameter.
  311. //• (Not used, this trip because some alignment coding is needed.
  312. //• I looks kind of cool in color mode, but must be aligned via
  313. //• bounce rect size.
  314. void DoLines ()
  315. {
  316.     short x, y;
  317.     
  318.     PenNormal ();
  319.     for (x = (diameter / 2); x < over; x += diameter)
  320.     {
  321.         MoveTo (x, 0);
  322.         LineTo (x, under);
  323.     
  324.         for (y = (diameter / 2); y < over; y += diameter)
  325.         {
  326.             MoveTo (0, y);
  327.             LineTo (over, y);
  328.         }
  329.     }
  330.     PenNormal ();
  331.     PenMode (srcXor);
  332. }
  333.  
  334. //• --------------------------------------------------------------- •//
  335. //• Caleed once per event loop.  Draws one sprite per event loop.
  336. void Draw ()
  337. {
  338.     short first, last;
  339.     
  340.     if (both)                            //• If square AND round...
  341.         if (toggle)                        //• If toogle is true...
  342.              PaintOval (&laceRect);        //• ...do an oval...
  343.          else                            //• ...if not...
  344.              PaintRect (&laceRect);        //• ...do a square.
  345.     
  346.     //• We're usually round...
  347.     if (round)
  348.          PaintOval (&laceRect);
  349.      else                        //• ...but it's hip to be square.
  350.          PaintRect (&laceRect);
  351.          
  352.      //• If use hits slash, we do the diamond tracks...
  353.      if (degrees_30)
  354.      {
  355.          //• Right direction.
  356.         if ((plus) && (down))
  357.             OffsetRect (&laceRect,   offset / 2,   offset);
  358.         if ((plus) && (up))
  359.             OffsetRect (&laceRect,   offset / 2, - offset);
  360.     
  361.         //• Left direction. 
  362.         if ((minus) && (down))
  363.             OffsetRect (&laceRect, - offset / 2,   offset);
  364.         if ((minus) && (up))
  365.             OffsetRect (&laceRect, - offset / 2, - offset);
  366.     }
  367.     //• ...but normally we're trackin' square paths.
  368.     else        //• 45 degrees.
  369.     {
  370.          //• Right direction.
  371.         if ((plus) && (down))        //• Down right wonderful!
  372.             OffsetRect (&laceRect,   offset,   offset);
  373.         if ((plus) && (up))            //• Up, right and vertical!
  374.             OffsetRect (&laceRect,   offset, - offset);
  375.     
  376.         //• Left direction. 
  377.         if ((minus) && (down))        //• Left down in the dumps!
  378.             OffsetRect (&laceRect, - offset,   offset);
  379.         if ((minus) && (up))        //• Left up to powers that be!
  380.             OffsetRect (&laceRect, - offset, - offset);
  381.     }
  382.     toggle = ! toggle;
  383. }
  384.  
  385. //• --------------------------------------------------------------- •//
  386. //• We're doing an rDocProc, with no resource.  This is so we still
  387. //• have a title bar to displat data in, yet black.
  388. //• It's a "C" window if not running on an antique!
  389. void SetUpWindow(void)
  390. {
  391.     dragRect = qd.screenBits.bounds;
  392.     
  393.     SetRect (&windRect, 0, 19, over, under);
  394.     
  395.     if (WeGotHues ())
  396.         laceWind = NewCWindow(0L, &windRect, title, yo, 16, (WindowPtr) -1L, yo, 0);
  397.     else
  398.         laceWind = NewWindow(0L, &windRect, title, yo, 16, (WindowPtr) -1L, yo, 0);
  399.  
  400.     SetPort(laceWind);
  401. }
  402.  
  403. //• --------------------------------------------------------------- •//
  404. //• Get those managers off their butts!
  405. void InitMacintosh(void)
  406. {
  407.     MaxApplZone();
  408.     
  409.     InitGraf(&qd.thePort);
  410.     InitFonts();
  411.     FlushEvents(everyEvent, 0);
  412.     InitWindows();
  413.     InitMenus();
  414.     TEInit();
  415.     InitDialogs(0L);
  416.     InitCursor();
  417. }
  418.  
  419. //• --------------------------------------------------------------- •//
  420. //• Not used much, but here if we want to add some tricks...
  421. void HandleMouseDown (EventRecord    *theEvent)
  422. {
  423.     WindowPtr    theWindow;
  424.     short windowCode = FindWindow (theEvent->where, &theWindow);
  425.     
  426.     switch (windowCode)
  427.     {
  428.         case inSysWindow: 
  429.             SystemClick (theEvent, theWindow);
  430.         break;
  431.             
  432.         case inContent:
  433.             if (theWindow == laceWind)
  434.             {
  435.                 if (theWindow != FrontWindow())
  436.                     SelectWindow(laceWind);
  437.                 else
  438.                     InvalRect(&laceWind->portRect);
  439.             }
  440.         break;
  441.             
  442.         case inGoAway:
  443.             if (theWindow == laceWind && 
  444.                 TrackGoAway(laceWind, theEvent->where))
  445.             ExitToShell();
  446.         break;
  447.     }
  448. }
  449.  
  450. //• --------------------------------------------------------------- •//
  451. //• An event is being held and YOU are invited!  If you go to the
  452. //• event, you're bound to get looped, eventually!
  453. short HandleEvent(void)
  454. {
  455.     int            ok;
  456.     EventRecord    theEvent;
  457.     char theKey;
  458.     RGBColor hue;
  459.     
  460.     HiliteMenu(0);
  461.     SystemTask ();        /* Handle desk accessories */
  462.     
  463.     ok = GetNextEvent (everyEvent, &theEvent);
  464.     if (ok)
  465.         switch (theEvent.what)
  466.         {
  467.             case mouseDown:
  468.                 HandleMouseDown(&theEvent);
  469.             break;
  470.             
  471.             //• Here's where we get most of our control.
  472.             case keyDown: 
  473.             case autoKey:
  474.                     theKey = (theEvent.message & charCodeMask);
  475.                     switch (theKey)
  476.                     {
  477.                         case 'a':
  478.                             DoAbout ();        //• What about it?
  479.                         break;
  480.                         
  481.                         case  'b':            //• Square meal in round can!
  482.                             round = no;
  483.                             square = no;
  484.                             both = yo;
  485.                             StartOver (no);
  486.                         break;
  487.                         
  488.                         case 'c':            //• Picker knows!
  489.                             if (! WeGotHues ())
  490.                                 break;
  491.  
  492.                             InitCursor ();
  493.                             SelectColor (&hue);
  494.                             HideCursor ();
  495.                             RGBBackColor (&hue);
  496.                             StartOver (yo);
  497.                         break;
  498.                         
  499.                         case 'd':
  500.                             bw = yo;
  501.                             BackColor (whiteColor);
  502.                             StartOver (yo); //• Get back, Loretta!
  503.                         break;
  504.                         
  505.                         case 'g':            //• Is this too much?
  506. //                             if (! bw)
  507. //                             {
  508. //                                 StartOver (no);
  509. //                                 DoLines ();
  510. //                             }
  511.                         break;
  512.                         
  513.                         case 'k':            //• What was that key?
  514.                             DoKeys ();        //• Show me!
  515.                         break;
  516.                         
  517.                         case 'p':            //• Pa's, paws, P. Oz.
  518.                             pause = ! pause;//• But, then, maybe not!
  519.                         break;
  520.                         
  521.                         case 'q':            //• Bail.
  522.                             quit = true;
  523.                         break;
  524.                         
  525.                         case 'r':            //• Round and round we go.
  526.                             round = yo;
  527.                             square = no;
  528.                             both = no;
  529.                             StartOver (no);
  530.                         break;
  531.                         
  532.                         case 's':            //• Equalateral quadrangle!
  533.                             round = no;
  534.                             square = yo;
  535.                             both = no;
  536.                             StartOver (no);
  537.                         break;
  538.                         
  539.                         case '+':            //• Fatten up our sprite.
  540.                             if (howWide > 98)
  541.                                 break;
  542.                             howWide += 1;
  543.                             howHigh += 1;
  544.                             StartOver (no); //• No reset.
  545.                         break;
  546.                         
  547.                         case '-':            //• Go on a diet.
  548.                             if (howWide < 5)
  549.                                 break;
  550.                             howWide -= 1;
  551.                             howHigh -= 1;
  552.                             StartOver (no);    //• No reset.
  553.                         break;
  554.                         
  555.                         case ']':            //• Step it up, a little!
  556.                             offset += 1;
  557.                             StartOver (no);
  558.                         break;
  559.                         
  560.                         case '[':            //• Whoa!  To fast!
  561.                             offset -= 1;
  562.                             StartOver (no);
  563.                         break;
  564.                         
  565.                         case '/':    //• The angle of the dangle.
  566.                             degrees_30 = ! degrees_30;
  567.                             StartOver (no);
  568.                         break;
  569.                     }
  570.             break;
  571.                 
  572.             case updateEvt:
  573.                 BeginUpdate(laceWind);
  574.                 
  575.                 //• No bulls, hit!
  576. //                DrawBullseye(((WindowPeek) laceWind)->hilited);
  577.                 EndUpdate(laceWind);
  578.             break;
  579.                     
  580.             case activateEvt:
  581.                 InvalRect(&laceWind->portRect);
  582.             break;
  583.         }
  584.     if (! pause)
  585.     {
  586.         FigureDirection ();
  587.         Draw();
  588.     }
  589. }
  590.  
  591. //• --------------------------------------------------------------- •//
  592. void main(void)
  593. {    
  594.     InitMacintosh();
  595. //    WeGotHues ();
  596.     Originals ();
  597.     HideMenuBar ();
  598.     HideCursor ();            //• Swat that fly!
  599.     SetUpWindow();
  600.     DoAbout ();
  601.     DoKeys ();
  602.     PenMode (srcXor);        //• This is so we leave tracks.
  603.  
  604.     while (! quit)
  605.         HandleEvent ();
  606.     PenNormal ();
  607.     ShowMenuBar ();
  608. }
  609. //• --------------------------------------------------------------- •//
  610. //• --------------------------------------------------------------- •//
  611.